﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;

namespace WF_Loadout_Editor
{
    public partial class ModForm : Form
    {
        public List<List<BaseMod>> Mods;
        // Warframe Mods
        List<BaseMod> warframeMods;
        public int iCurrentwarframeMod;
        int iwarframeOldValue;
        // Rifle Mods
        List<BaseMod> rifleMods;
        public int iCurrentrifleMod;
        int irifleOldValue;
        // Shotgun Mods
        List<BaseMod> shotgunMods;
        public int iCurrentshotgunMod;
        int ishotgunOldValue;
        // Pistol Mods
        List<BaseMod> pistolMods;
        public int iCurrentpistolMod;
        int ipistolOldValue;
        // Melee Mods
        List<BaseMod> meleeMods;
        public int iCurrentmeleeMod;
        int imeleeOldValue;
        // Sentinel Mods
        List<BaseMod> sentinelMods;
        public int iCurrentsentinelMod;
        int isentinelOldValue;

        // add/remove mod event
        public event EventHandler AddMod;
        public event EventHandler RemoveMod;

        public ModForm()
        {
            InitializeComponent();

            warframeMods = new List<BaseMod>();
            rifleMods = new List<BaseMod>();
            shotgunMods = new List<BaseMod>();
            pistolMods = new List<BaseMod>();
            meleeMods = new List<BaseMod>();
            sentinelMods = new List<BaseMod>();
            Mods = new List<List<BaseMod>>();

            // Load warframe mods
            XElement ModRoot = XElement.Load("Resources/XML/Mods.xml");
            XElement xWarframes = ModRoot.Element("WarframeMods");
            IEnumerable<XElement> EWarframes = xWarframes.Elements("WarframeMod");
            ImportWarframeMods(EWarframes, warframeMods);

            // Load rifle mods
            XElement xRifles = ModRoot.Element("RifleMods");
            IEnumerable<XElement> ERifles = xRifles.Elements("RifleMod");
            ImportWeaponMods(ERifles, rifleMods, ModType.Rifle);

            
            // Load shotgun mods
            XElement xShotguns = ModRoot.Element("ShotgunMods");
            IEnumerable<XElement> EShotgun = xShotguns.Elements("ShotgunMod");
            ImportWeaponMods(EShotgun, shotgunMods, ModType.Shotgun);

            // Load pistol mods
            XElement xPistols = ModRoot.Element("PistolMods");
            IEnumerable<XElement> EPistols = xPistols.Elements("PistolMod");
            ImportWeaponMods(EPistols, pistolMods, ModType.Pistol);

            // Load melee mods
            XElement xMelees = ModRoot.Element("MeleeMods");
            IEnumerable<XElement> EMelees = xMelees.Elements("MeleeMod");
            ImportWeaponMods(EMelees, meleeMods, ModType.Melee);

            /* TODO: EDIT THE SENTINEL MOD FILE
            // Load sentinel mods
            XElement xSentinels = ModRoot.Element("SentinelMods");
            IEnumerable<XElement> ESentinels = xSentinels.Elements("SentinelMod");
            ImportMods(ESentinels, sentinelMods, 5);*/
            iCurrentwarframeMod =
                iCurrentrifleMod =
                iCurrentshotgunMod =
                iCurrentpistolMod =
                iCurrentmeleeMod =
                iCurrentsentinelMod =
                WarframeModLB.SelectedIndex =
                iwarframeOldValue =
                irifleOldValue =
                ishotgunOldValue =
                ipistolOldValue =
                imeleeOldValue =
                isentinelOldValue = 0;
        }

        public void ImportWarframeMods(IEnumerable<XElement> IEelements, List<BaseMod> mods)
        {
            foreach (XElement xElement in IEelements)
            {
                XAttribute xName = xElement.Attribute("Name");
                XElement xDescrip = xElement.Element("Description");
                XElement xCStat = xElement.Element("currentStat");
                XElement xSModifier = xElement.Element("statModifier");
                XElement xCCost = xElement.Element("currentCost");
                XElement xSType = xElement.Element("StatType");
                XElement xMRank = xElement.Element("maxRank");
                XElement xPol = xElement.Element("Polarity");
                Polarity newPolarity = new Polarity(Convert.ToInt32(xPol.Value),-1);

                WarframeMod newMod = new WarframeMod(Convert.ToString(xName.Value),
                                             Convert.ToString(xDescrip.Value), ModType.Warframe, newPolarity,
                                             (float)Convert.ToDouble(xSModifier.Value),
                                             (float)Convert.ToDouble(xCStat.Value), 0,
                                             Convert.ToInt32(xMRank.Value),
                                             Convert.ToInt32(xCCost.Value),
                                             Convert.ToInt32(xSType.Value));

                mods.Add(newMod);
            }

            Mods.Add(mods);
        }

        public void ImportWeaponMods(IEnumerable<XElement> IEelements, List<BaseMod> mods, ModType type)
        {
            foreach (XElement xElement in IEelements)
            {
                XAttribute xName = xElement.Attribute("Name");
                XElement xDescrip = xElement.Element("Description");
                XElement xCStat = xElement.Element("currentStat");
                XElement xSModifier = xElement.Element("statModifier");
                XElement xCCost = xElement.Element("currentCost");
                XElement xSType = xElement.Element("StatType");
                XElement xMRank = xElement.Element("maxRank");
                XElement xPol = xElement.Element("Polarity");
                Polarity newPolarity = new Polarity(Convert.ToInt32(xPol.Value),-1);

                WeaponMod newMod = new WeaponMod(Convert.ToString(xName.Value),
                                             Convert.ToString(xDescrip.Value), type, newPolarity,
                                             (float)Convert.ToDouble(xSModifier.Value),
                                             (float)Convert.ToDouble(xCStat.Value), 0,
                                             Convert.ToInt32(xMRank.Value),
                                             Convert.ToInt32(xCCost.Value),
                                             Convert.ToInt32(xSType.Value));

                mods.Add(newMod);
            }

            Mods.Add(mods);
        }

        // change mod page
        private void ModTC_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (ModTC.SelectedIndex == 0)
                WarframeModLB.SelectedIndex = iCurrentwarframeMod;
            else if (ModTC.SelectedIndex == 1)
                RifleModLB.SelectedIndex = iCurrentrifleMod;
            else if (ModTC.SelectedIndex == 2)
                ShotgunModLB.SelectedIndex = iCurrentshotgunMod;
            else if (ModTC.SelectedIndex == 3)
                PistolModLB.SelectedIndex = iCurrentpistolMod;
            else if (ModTC.SelectedIndex == 4)
                MeleeModLB.SelectedIndex = iCurrentmeleeMod;
            else if (ModTC.SelectedIndex == 5)
                SentinelModLB.SelectedIndex = iCurrentsentinelMod;
        }

        // change current warframe mod
        private void WarframeModLB_SelectedIndexChanged(object sender, EventArgs e)
        {
            iCurrentwarframeMod = WarframeModLB.SelectedIndex;

            // updates the text boxes
            WarframeModDescriptionTB.Text = Mods[ModTC.SelectedIndex][iCurrentwarframeMod].Description;
            WarframeModStatTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentwarframeMod].CurrentStat);
            WarframeModCostTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentwarframeMod].BaseCost);
            WarframeModRankNUD.Maximum = Mods[ModTC.SelectedIndex][iCurrentwarframeMod].MaxRank;
            
            // sets the current mod image
            WarframeModPicture.BackgroundImage = Mods[ModTC.SelectedIndex][iCurrentwarframeMod].Picture;
        }

        // change current rifle mod
        private void RifleModLB_SelectedIndexChanged(object sender, EventArgs e)
        {
            iCurrentrifleMod = RifleModLB.SelectedIndex;

            // updates the text boxes
            RifleModDescriptionTB.Text = Mods[ModTC.SelectedIndex][iCurrentrifleMod].Description;
            RifleModStatTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentrifleMod].CurrentStat);
            RifleModCostTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentrifleMod].BaseCost);
            RifleModRankNUD.Maximum = Mods[ModTC.SelectedIndex][iCurrentrifleMod].MaxRank;

            // sets the current mod image
            RifleModPicture.BackgroundImage = Mods[ModTC.SelectedIndex][iCurrentrifleMod].Picture;
        }

        // change current shotgun mod
        private void ShotgunModLB_SelectedIndexChanged(object sender, EventArgs e)
        {
            iCurrentshotgunMod = ShotgunModLB.SelectedIndex;

            // updates the text boxes
            ShotgunModDescriptionTB.Text = Mods[ModTC.SelectedIndex][iCurrentshotgunMod].Description;
            ShotgunModStatTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentshotgunMod].CurrentStat);
            ShotgunModCostTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentshotgunMod].BaseCost);
            ShotgunModRankNUD.Maximum = Mods[ModTC.SelectedIndex][iCurrentshotgunMod].MaxRank;

            // sets the current mod image
            ShotgunModPicture.BackgroundImage = Mods[ModTC.SelectedIndex][iCurrentshotgunMod].Picture;
        }

        // change current pistol mod
        private void PistolModLB_SelectedIndexChanged(object sender, EventArgs e)
        {
            iCurrentpistolMod = PistolModLB.SelectedIndex;

            // updates the text boxes
            PistolModDescriptionTB.Text = Mods[ModTC.SelectedIndex][iCurrentpistolMod].Description;
            PistolModStatTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentpistolMod].CurrentStat);
            PistolModCostTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentpistolMod].BaseCost);
            PistolModRankNUD.Maximum = Mods[ModTC.SelectedIndex][iCurrentpistolMod].MaxRank;
            PistolModRankNUD.Maximum = Mods[ModTC.SelectedIndex][iCurrentpistolMod].MaxRank;

            // sets the current mod image
            PistolModPicture.BackgroundImage = Mods[ModTC.SelectedIndex][iCurrentpistolMod].Picture;
        }

        // change current melee mod
        private void MeleeModLB_SelectedIndexChanged(object sender, EventArgs e)
        {
            iCurrentmeleeMod = MeleeModLB.SelectedIndex;

            // updates the text boxes
            MeleeModDescriptionTB.Text = Mods[ModTC.SelectedIndex][iCurrentmeleeMod].Description;
            MeleeModStatTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentmeleeMod].CurrentStat);
            MeleeModCostTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentmeleeMod].BaseCost);
            MeleeModRankNUD.Maximum = Mods[ModTC.SelectedIndex][iCurrentmeleeMod].MaxRank;

            // sets the current mod image
            MeleeModPicture.BackgroundImage = Mods[ModTC.SelectedIndex][iCurrentmeleeMod].Picture;
        }

        // change current sentinel mod
        private void SentinelModLB_SelectedIndexChanged(object sender, EventArgs e)
        {
            // TODO: ADD SENTINEL MODS
            /*
            iCurrentsentinelMod = MeleeModLB.SelectedIndex;
            
            // updates the text boxes
            SentinelModDescriptionTB.Text = Mods[ModTC.SelectedIndex][iCurrentsentinelMod].Description;
            SentinelModStatTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentsentinelMod].CurrentStat);
            SentinelModCostTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentsentinelMod].CurrentCost);
            SentinelModRankNUD.Maximum = Mods[ModTC.SelectedIndex][iCurrentsentinelMod].MaxRank;
            
            // sets the current mod image
            SentinelModPicture.BackgroundImage = Mods[ModTC.SelectedIndex][iCurrentsentinelMod].Picture;
            */
        }

        // increase warframe mod rank
        private void WarframeModRankNUD_ValueChanged(object sender, EventArgs e)
        {
            if (WarframeModRankNUD.Value > iwarframeOldValue)
            {
                ++Mods[ModTC.SelectedIndex][iCurrentwarframeMod].BaseCost;
                Mods[ModTC.SelectedIndex][iCurrentwarframeMod].CurrentStat += Mods[ModTC.SelectedIndex][iCurrentwarframeMod].StatModifier;
            }
            else
            {
                --Mods[ModTC.SelectedIndex][iCurrentwarframeMod].BaseCost;
                Mods[ModTC.SelectedIndex][iCurrentwarframeMod].CurrentStat -= Mods[ModTC.SelectedIndex][iCurrentwarframeMod].StatModifier;
            }

            // updates the text boxes
            iwarframeOldValue = Convert.ToInt32(WarframeModRankNUD.Value);
            WarframeModStatTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentwarframeMod].CurrentStat);
            WarframeModCostTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentwarframeMod].BaseCost);
        }

        // increase rifle mod rank
        private void RifleModRankNUD_ValueChanged(object sender, EventArgs e)
        {
            if (RifleModRankNUD.Value > irifleOldValue)
            {
                ++Mods[ModTC.SelectedIndex][iCurrentrifleMod].BaseCost;
                Mods[ModTC.SelectedIndex][iCurrentrifleMod].CurrentStat += Mods[ModTC.SelectedIndex][iCurrentrifleMod].StatModifier;
            }
            else
            {
                --Mods[ModTC.SelectedIndex][iCurrentrifleMod].BaseCost;
                Mods[ModTC.SelectedIndex][iCurrentrifleMod].CurrentStat -= Mods[ModTC.SelectedIndex][iCurrentrifleMod].StatModifier;
            }

            // updates the text boxes 
            irifleOldValue = Convert.ToInt32(RifleModRankNUD.Value);
            RifleModStatTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentrifleMod].CurrentStat);
            RifleModCostTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentrifleMod].BaseCost);
        }

        // increase shotgun mod rank
        private void ShotgunModRankNUD_ValueChanged(object sender, EventArgs e)
        {
            if (ShotgunModRankNUD.Value > ishotgunOldValue)
            {
                ++Mods[ModTC.SelectedIndex][iCurrentshotgunMod].BaseCost;
                Mods[ModTC.SelectedIndex][iCurrentshotgunMod].CurrentStat += Mods[ModTC.SelectedIndex][iCurrentshotgunMod].StatModifier;
            }
            else
            {
                --Mods[ModTC.SelectedIndex][iCurrentshotgunMod].BaseCost;
                Mods[ModTC.SelectedIndex][iCurrentshotgunMod].CurrentStat -= Mods[ModTC.SelectedIndex][iCurrentshotgunMod].StatModifier;
            }

            // updates the text boxes
            ishotgunOldValue = Convert.ToInt32(ShotgunModRankNUD.Value);
            ShotgunModStatTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentshotgunMod].CurrentStat);
            ShotgunModCostTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentshotgunMod].BaseCost);
        }

        // increase pistol mod rank
        private void PistolModRankNUD_ValueChanged(object sender, EventArgs e)
        {
            if (PistolModRankNUD.Value > ipistolOldValue)
            {
                ++Mods[ModTC.SelectedIndex][iCurrentpistolMod].BaseCost;
                Mods[ModTC.SelectedIndex][iCurrentpistolMod].CurrentStat += Mods[ModTC.SelectedIndex][iCurrentpistolMod].StatModifier;
            }
            else
            {
                --Mods[ModTC.SelectedIndex][iCurrentpistolMod].BaseCost;
                Mods[ModTC.SelectedIndex][iCurrentpistolMod].CurrentStat -= Mods[ModTC.SelectedIndex][iCurrentpistolMod].StatModifier;
            }

            // updates the text boxes
            ipistolOldValue = Convert.ToInt32(PistolModRankNUD.Value);
            PistolModStatTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentpistolMod].CurrentStat);
            PistolModCostTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentpistolMod].BaseCost);
        }

        // increase melee mod rank
        private void MeleeModRankNUD_ValueChanged(object sender, EventArgs e)
        {
            if (MeleeModRankNUD.Value > imeleeOldValue)
            {
                ++Mods[ModTC.SelectedIndex][iCurrentmeleeMod].BaseCost;
                Mods[ModTC.SelectedIndex][iCurrentmeleeMod].CurrentStat += Mods[ModTC.SelectedIndex][iCurrentmeleeMod].StatModifier;
            }
            else
            {
                --Mods[ModTC.SelectedIndex][iCurrentmeleeMod].BaseCost;
                Mods[ModTC.SelectedIndex][iCurrentmeleeMod].CurrentStat -= Mods[ModTC.SelectedIndex][iCurrentmeleeMod].StatModifier;
            }

            // updates the text boxes
            imeleeOldValue = Convert.ToInt32(MeleeModRankNUD.Value);
            MeleeModStatTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentmeleeMod].CurrentStat);
            MeleeModCostTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentmeleeMod].BaseCost);
        }

        // increase sentinel mod rank
        private void SentinelModRankNUD_ValueChanged(object sender, EventArgs e)
        {
            /*// TODO 
            if (SentinelModRankNUD.Value > isentinelOldValue)
            {
                ++Mods[ModTC.SelectedIndex][iCurrentsentinelMod].CurrentCost;
                Mods[ModTC.SelectedIndex][iCurrentsentinelMod].CurrentStat += Mods[ModTC.SelectedIndex][iCurrentsentinelMod].IncrementStat;
            }
            else
            {
                --Mods[ModTC.SelectedIndex][iCurrentsentinelMod].CurrentCost;
                Mods[ModTC.SelectedIndex][iCurrentsentinelMod].CurrentStat -= Mods[ModTC.SelectedIndex][iCurrentsentinelMod].IncrementStat;
            }

            isentinelOldValue = Convert.ToInt32(SentinelModRankNUD.Value);
            SentinelModStatTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentsentinelMod].CurrentStat);
            SentinelModCostTB.Text = Convert.ToString(Mods[ModTC.SelectedIndex][iCurrentsentinelMod].CurrentCost);
           */
        }
        private void AddModButton_Click(object sender, EventArgs e)
        {
            if (AddMod != null)
            {
                AddMod(this, new EventArgs());
            }
        }

        private void RemoveModButton_Click(object sender, EventArgs e)
        {
            if (RemoveMod != null)
            {
                RemoveMod(this, new EventArgs());
            }
        }
    }
}
